package com.hsd.whb.wav;

import lombok.Data;

import java.io.IOException;
import java.io.OutputStream;

@Data
public class WavFile {

    private byte[] data;

    private byte[] RIFF = "RIFF".getBytes();
    private byte[] RIFF_SIZE = new byte[4];
    private byte[] RIFF_TYPE = "WAVE".getBytes();

    private byte[] FORMAT = "fmt ".getBytes();
    private byte[] FORMAT_SIZE = new byte[4];
    private byte[] FORMATTAG = new byte[2];
    private byte[] CHANNELS = new byte[2];
    private byte[] SamplesPerSec = new byte[4];
    private byte[] AvgBytesPerSec = new byte[4];
    private byte[] BlockAlign = new byte[2];
    private byte[] BitsPerSample = new byte[2];

    private byte[] DataChunkID = "data".getBytes();
    private byte[] DataSize = new byte[4];

    public WavFile(byte[] data) {
        this.data = data;
        this.init();
    }

    public byte[] intToBytes(int num) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) (num & 0xFF);
        bytes[1] = (byte) ((num >> 8) & 0xFF);
        bytes[2] = (byte) (num >> 16 & 0xFF);
        bytes[3] = (byte) ((num >> 24) & 0xFF);
        return bytes;
    }

    public void init() {
        DataSize = intToBytes(this.data.length);
        RIFF_SIZE = intToBytes(this.data.length + 36);

        FORMAT_SIZE = new byte[]{(byte) 16, (byte) 0, (byte) 0, (byte) 0};
        FORMATTAG = new byte[]{1, 0};
        CHANNELS = new byte[]{1, 0};
        SamplesPerSec = intToBytes(16000);
        AvgBytesPerSec = intToBytes(32000);
        BlockAlign = new byte[]{2, 0};
        BitsPerSample = new byte[]{16, 0};
    }

    public void write(OutputStream outputStream) throws IOException {
        outputStream.write(RIFF);
        outputStream.write(RIFF_SIZE);
        outputStream.write(RIFF_TYPE);
        outputStream.write(FORMAT);
        outputStream.write(FORMAT_SIZE);
        outputStream.write(FORMATTAG);
        outputStream.write(CHANNELS);
        outputStream.write(SamplesPerSec);
        outputStream.write(AvgBytesPerSec);
        outputStream.write(BlockAlign);
        outputStream.write(BitsPerSample);

        outputStream.write(DataChunkID);
        outputStream.write(DataSize);
        outputStream.write(data);
        outputStream.flush();
    }

}
